using System;
using System.Collections.Generic;
using System.Linq;
using System.Security.Cryptography;
using System.Text;
using System.Threading.Tasks;

namespace backend.Services
{
    public class PasswordHasher
    {
        public static string HashPassword(string password)
        {
            // 生成一个随机的盐
            using (var rng = RandomNumberGenerator.Create())
            {
                var salt = new byte[64 / 8]; // 使用64位盐
                rng.GetBytes(salt);

                // 使用 SHA256 生成哈希值
                using (var sha256 = SHA256.Create())
                {
                    var hash = sha256.ComputeHash(Encoding.UTF8.GetBytes(password));
                    
                    // 只取前16字节(128位)，以便Base64编码后长度更短
                    var shortHash = hash.Take(16).ToArray();

                    // 将盐和哈希值合并成一个数组
                    var result = new byte[salt.Length + shortHash.Length];
                    Buffer.BlockCopy(salt, 0, result, 0, salt.Length);
                    Buffer.BlockCopy(shortHash, 0, result, salt.Length, shortHash.Length);

                    // 转换为Base64编码的字符串
                    return Convert.ToBase64String(result);
                }
            }
        }

        public static bool VerifyPassword(string plainTextPassword, string hashedPassword)
        {
            // 解码存储的哈希值为字节数组
            var hashedPasswordBytes = Convert.FromBase64String(hashedPassword);

            // 分离盐和哈希值
            var saltLength = 64 / 8;
            var salt = new byte[saltLength];
            var hash = new byte[hashedPasswordBytes.Length - saltLength];

            Buffer.BlockCopy(hashedPasswordBytes, 0, salt, 0, salt.Length);
            Buffer.BlockCopy(hashedPasswordBytes, salt.Length, hash, 0, hash.Length);

            // 再次使用相同的参数生成一个新的哈希值
            using (var sha256 = SHA256.Create())
            {
                var newHash = sha256.ComputeHash(Encoding.UTF8.GetBytes(plainTextPassword));
                var newShortHash = newHash.Take(16).ToArray();

                // 比较新生成的哈希值和存储的哈希值
                return CryptographicOperations.FixedTimeEquals(hash, newShortHash);
            }
        }
    }
}